home *** CD-ROM | disk | FTP | other *** search
- TITLE FSWAP.ASM
- ; (***************************************************************************
- ;
- ; RELEASE 1.00 - as contained in the file
- ; by Peter Holschbach, 2:2450/660.3, GERMANY
- ;
- ; --------------------------------------------
- ; organized for Fido's PASCAL related echoes
- ; --------------------------------------------
- ;
- ; 09/01/1994 to --/--/---- by Peter Holschbach, 2:2450/660.3, GERMANY
- ;
- ;
- ; As far as third party copyrights are not violated this
- ; source code is hereby placed to the public domain. Use
- ; it whatever way you want, but use AT YOUR OWN RISK.
- ;
- ; In case you should modify the source rather send your
- ; modifications to the unit's current organizer (see above for
- ; NM address) than to spread it on your own. This will help to
- ; keep the unit updated and grant a certain standard to all
- ; other users as well.
- ;
- ; The unit is currently still under work. So it might greatly
- ; benefit of your participation.
- ;
- ; Those who contributed to the following piece of source,
- ; listed in alphabethical order:
- ; ================================================================
- ; Peter Holschbach ...
- ; ================================================================
- ; YOUR NAME WILL APPEAR HERE IF YOU CONTRIBUTE USEFUL SOURCE.
- ;
- ; Credits in your own programs are as welcome as unnecessary.
- ;
- ;***************************************************************************)
- ;
- ; Assembler: tested only with TASM 3.2
- ; Call: TASM /M3 FSWAP.ASM
- ;
- ;***************************************************************************)
-
- .8086 ; OK! the last PC at the world should use it
- JUMPS ; use long jumps if needed
- LOCALS @@ ; every label started with @@ is local
-
- ;-----------------------------------------------------------------------------
-
- PUBLIC SwapExec
-
- ;-----------------------------------------------------------------------------
-
- EXTRN DosRetValue : Word ; global variable for return value
- EXTRN PrefixSeg : Word
- EXTRN SwapFilePath : Byte ; it's a string
-
- ;-----------------------------------------------------------------------------
-
- DosBlockSize EQU 0FFF0H ; there are problems to write FFFFh,
- ; max. FFFAh Bytes will be written.
- ; ! use ony a size MOD 16 !
-
- IF (DosBlockSize MOD 16) NE 0
- ERR "The size of DosBlockSize should be a value MOD 16 !"
- ENDIF
-
- EmsPageSize EQU 16 * 1024
-
- ;-------------------------- error messages from "SwapExec"
-
- ErrDeviceNotAvailable EQU 0001 ; EMS/XMS not available
- ErrSizeCalc EQU 0002 ; start is bigger then last
- ErrNotEnoughSpace EQU 0003 ; EMS/XMS/Disk
- ErrCantGetSize EQU 0004 ; Disk
- ErrCreateTempFile EQU 0005 ; Disk
- ErrWriteFile EQU 0006 ; Disk
- ErrReadFile EQU 0007 ; Disk
- ErrCheckSizeToSave EQU 0008
- ErrAllocation EQU 0009
- ErrSwapOut EQU 0010
-
- ; MSB
-
- ErrMemReduce EQU 11 ; -> LSB = error from DOS
- ErrManager EQU 0FFh ; -> MSB = error message from XMS/EMS
-
- ;-------------------------- definitions for easy acces
-
- hi EQU (Word PTR 2)
- lo EQU (Word PTR 0)
-
- ofst EQU (Word PTR 0)
- segm EQU (Word PTR 2)
-
- hidden EQU 2
- sys EQU 4
- SwapFileAttr EQU hidden+sys
-
- ;-----------------------------------------------------------------------------
- ; The definitoins of some structures
- ;-----------------------------------------------------------------------------
-
- ; ----------- structur to copy data from/to EMS
- EMSstrucTyp STRUC
- RegionLength DD ? ; length of memory region to copy (in byte)
-
- SourceMemoryTyp DB ? ; 0=conventional memory / 1=EMS
- SourceHandle DW ? ; 0=conventional memory
- SourceInitialOffset DW ? ; offset in source from which to begin
- SourceInitialSegPage DW ? ; segment in source from which to begin
-
- DestMemoryTyp DB ? ; 0=conventional memory / 1=EMS
- DestHandle DW ? ; 0=conventional memory
- DestInitialOffset DW ? ; offset in destination from which to begin
- DestInitialSegPage DW ? ; segment in destination from which to begin
- ENDS
- ; ----------- structure for exec
-
- ExexStrucTyp STRUC
- EnvironmSeg DW ? ; 0 = copy parent Environment
- ParamString DD ? ; max. 128 Bytes
- FCB1 DD ?
- FCB2 DD ?
- ENDS
-
- ; ----------- structur to copy data from/to XMS
- XMSstrucTyp STRUC
- BytesToMove DD ? ; how many bytes to move
- HandleS DW ? ; if source = XMS the handle number
- PtrS DD ? ; if source = Memory a Pointer at the beginning
- HandleD DW ? ; if destination = XMS the handle number
- PtrD DD ? ; if dest. = memory a Pointer at the beginning
- ENDS
-
-
- ;-----------------------------------------------------------------------------
- ; The definitions of some macros
- ;-----------------------------------------------------------------------------
-
- ; --------- simple case macro to CALL depending of a value in AL
-
- Case MACRO CaseVar,destinations,OkAddr
- LOCAL @@endcase
- count = 0
-
- MOV AL,CaseVar
- IRP jumpTo,destinations,OkAddr
- LOCAL @@J&count
- CMP AL,count
- JNE @@J&count
- CALL jumpTo
- JNC OkAddr
- JMP @@endcase
- @@J&count:
- count = count + 1
- ENDM
- @@endcase:
- ENDM
-
- ; --------- copy a pascal string in CS and use "0" as terminator
-
- CopyPascalString MACRO Source,Destination
- LOCAL @@emptyString
- PUSH DS
- LDS SI,Source
-
- MOV AX,SEG Destination
- MOV ES,AX
- LEA DI,Destination
-
- LODSB ; size of string in AL
- CMP AL,0 ; empty string ?
- JE @@emptyString
- MOV CL,AL
- XOR CH,CH ; CX = size
- REP_FastMovs
- @@emptyString:
- XOR AL,AL
- STOSB
- POP DS
- ENDM
-
- ; --------- macro to use MOVSW
-
- REP_FastMovs MACRO
- LOCAL @@noByteLeft
- SHR CX,1
- REP MOVSW
- JNC @@noByteLeft
- MOVSB
- @@noByteLeft:
-
- ENDM
-
- ;##########################################################################
- ; and now the first code
- ;##########################################################################
-
- .MODEL LARGE
- .CODE
-
- ;--------------------------------------------------
- ; All variables in CS who are needed after swap out
- ;--------------------------------------------------
-
- ;-------- variables needed for EMS
-
- EMSmovStruc EMSstrucTyp ?
-
- ;-------- variables used for XMS
-
- XMSPointer DD ?
-
- ;-------- variables for exec
-
- ProgPathName DB 80 DUP (?)
-
- ProgParam DB 128 DUP (?)
- nFCB1 DB 16 DUP (?)
- nFCB2 DB 16 DUP (?)
-
- ExexStruc ExexStrucTyp {EnvironmSeg=0, ParamString=ProgParam,FCB1=nFCB1,FCB2=nFCB2}
-
- ;----------------
-
- myPSP DW ?
- MaxSize DW ? ; aktual size of the program
- MinSize DW ? ; the minimal size of this program
- ; in paragraphs
- ;----------------
-
- EnAdress DD ? ; last Adress to save
- Handle DW ? ; then Handle for DISC/EMS/XMS
-
- MethodCS DB ?
-
- RetValue DW ?
- SaveSize DD ?
-
- ;-------- everything for the stack
-
- SaveSP DW ?
- SaveSS DW ?
-
- OriginSP DW ?
- OriginSS DW ?
-
- DW 50 DUP (?)
- TmpStack LABEL WORD
-
-
- ;----------------------------------------------------------------------------
- ; the function that must be called from Turbo Pascal
- ;----------------------------------------------------------------------------
- ;Function SwapExec (FileName,Parameter : String; LastAdr : Pointer; Method : TSwapMemTyp): Word;
-
- SwapExec PROC PASCAL FAR FileName : DWORD,Parameter : DWORD, LastAdr : DWord, Method : Byte
-
- PUSH DS ; save the datasegment
-
- CALL CopyFromTurbo
- MOV AX,ErrCheckSizeToSave ; nothing to save ?
- JE Exit1
-
- ;--------------- check if memorytyp is available
-
- CASE MethodCS,<CheckXMSDriver,CheckEMSDriver,CheckDiskDriver>,DeviceOK
-
- ; -------------- errorhandler "device not available"
- DeviceError:
-
- MOV AX,ErrDeviceNotAvailable
- JMP Exit1
- DeviceOK:
- ;--------------- allocate memory
-
- CASE MethodCS,<XMSAllocate,EMSAllocate,DiskAllocate>,AlloCationOk
-
- ;--------------- allocation error
- AllocationError:
- MOV AX,ErrAllocation
- JMP Exit1
-
- ;--------------- swap to memory or disk
- AlloCationOk:
- MOV Handle,DX ; save the handle
-
- CASE MethodCS,<SwapXms,SwapEMS,SwapDisk>,SwapOk
- JMP Exit1
-
- swapError:
- ;--------------- problem while swapout
-
- CASE MethodCS,<XMSDeAllocate,EMSDeAllocate,DiskDeAllocate>,ProbDealloc
-
- ; ignore any error
- ProbDealloc:
- MOV AX,ErrSwapOut
- JMP Exit1;
-
- SwapOk:
- ;--------------- save origin stack and switch to temporary stack
-
- MOV OriginSP,SP
- MOV AX,SS
- MOV OriginSS,AX ; save origin stack
- MOV AX,SEG TmpStack
- MOV SS,AX ; interrupt will be disabled
- ; for the next command
- LEA SP,TmpStack ; use stack in codesegment
-
- ; ---------- reduce memory
-
- MOV AX,MyPSP
- MOV ES,AX ; ES = MCB
- MOV BX,MinSize
- MOV AH,4Ah
- INT 21h ; set memory to new size
- MOV AH,AL
- MOV AL,ErrMemReduce
- JNC reduceOk
-
- MOV CX,OriginSS
- MOV BX,OriginSP
- MOV SS,CX
- MOV SP,BX
- JMP Exit1
-
- reduceOk:
- ; ---------- exec
-
- PUSH DS
- PUSH BP ; save it for TurboPasal
-
- PUSH CS
- POP DS
- PUSH CS
- POP ES ; DS = ES = CS
-
- LEA SI,ProgPathName
- LEA DI,nFCB1
- MOV AX,2901h
- INT 21h
-
- LEA DI,nFCB2
- MOV AX,2901h
- INT 21h
-
- LEA BX,ExexStruc
- LEA DX,ProgPathName
- MOV SaveSP,SP ; some DOS versions use ist
- MOV SaveSS,SS ; without restoring it
- CLD ; some DOS versions need this !
- MOV AX,4B00h
- INT 21h
- MOV SS,SaveSS ; disable interrupt ! until
- MOV SP,SaveSP ; next command
- JC ExecErr
- XOR AX,AX
- ExecErr:
- POP BP
- POP DS
- MOV RetValue,AX
-
- ; ---------- expand memory
-
- MOV AX,MyPSP
- MOV ES,AX
- MOV BX,MaxSize
- MOV AH,4Ah
- INT 21h
- JNC ExpandOk
-
- ; --- error -> no rescue
-
- MOV AX,4CFFh ; terminate process
- INT 21h
-
- ExpandOk:
-
- CASE MethodCS,<SwapInXms,SwapInEMS,SwapInDisk>,isSwapIn
- swapInError:
- MOV AX,4CFFh ; terminate process
- INT 21h
-
- isSwapIn:
- MOV AX,RetValue
- MOV DosRetValue,AX
- MOV CX,AX ; save return value
- MOV AX,OriginSS
- MOV BX,OriginSP
- MOV SS,AX
- MOV SP,BX
-
- CASE MethodCS,<XMSDeAllocate,EMSDeAllocate,DiskDeAllocate>,isDeAllocated
- JMP EXIT1
- deAllocError:
-
- isDeAllocated:
- MOV AX,0
-
- Exit1: ;--------------- clear only the stack and exit
- POP DS
- RET
-
- ENDP
-
- ;--------------------------------------------------------------------------
- ;--------------------------------------------------------------------------
-
- SwapInDisk PROC
- PUSH DS
-
- ; ---------------- set write pointer to beginning of file
- MOV AX,4200h ; move file pointer, from start of file
- MOV BX,Handle ; Handle number
- MOV CX,0
- MOV DX,0 ; Offset = 0
- INT 21h
-
- ; --------------- prepare reading
-
- LES DI,SaveSize ; ES,DI = Size to save
-
- MOV DX,OFFSET SavePoint
- MOV AX,SEG SavePoint
- MOV DS,AX ; DS,DX = pointer at start
-
- ; --------------- read from disk
- @@readLoop:
- MOV BX,Handle ; Handle number
- MOV CX,DosBlockSize ; read max. blocksize
- MOV AX,ES
- CMP AX,0 ; less then 64k to read ?
- JNE @@savemax ; no -> full size
- CMP DI,DosBlockSize
- JNB @@savemax ; if there is more then one block
- MOV CX,DI ; save the rest
- @@savemax:
- MOV AH,3Fh ; read from a file
- PUSH DX
- PUSH ES
- PUSH DI
- INT 21h
- POP DI
- POP ES
- POP DX
- JC @@readErr ; error during reading ?
- CMP AX,CX ; check if all bytes are read
- JNE @@readErr ; error during reading ?
- SUB DI,AX ; size to save = size to save - saved
- MOV AX,ES
- SBB AX,0
- MOV ES,AX ; ES,DI = ES,DI - CX = size to read
-
- ADD AX,DI ; ES+DI = 0 -> nothing left to read
- CMP AX,0
- JE @@ready
-
- MOV AX,DS
- ADD AX,DosBlockSize/16 ; next Segment to read
- MOV DS,AX
- JMP @@readloop
- @@ready:
- POP DS
- MOV AH,3Eh ; close handle
- INT 21h
- CLC
- RET
-
- @@readErr:
- ; if a error occures, the program must be stopped
-
- MOV AX,4CFFh ; terminate process
- INT 21h
- ENDP
-
- ;--------------------------------------------------------------------------
-
- SwapInEMS PROC
- PUSH DS ; save Turbo's DS
- PUSH CS
- POP DS
- PUSH CS
- POP ES ; DS = ES = CS
-
- LEA SI,SaveSize
- LEA DI,EMSmovStruc.RegionLength
- MOVSW
- MOVSW ; copy the length
-
- MOV AL,1
- STOSB ; copy from EMS
- MOV AX,Handle
- STOSW
- XOR AX,AX
- STOSW
- STOSW
-
- XOR AX,AX
- STOSB ; dest memory type = conventional
- STOSW ; handle = 0
- MOV AX,OFFSET SavePoint
- STOSW
- MOV AX,SEG SavePoint
- STOSW ; start from "SavePoint"
-
- LEA SI,EMSmovStruc.RegionLength
- MOV AX,5700h
- INT 67h
- POP DS
- OR AH,AH
- JNZ @@EMSerror
- RET
- @@EMSerror:
- ; if a error occures, the program must be stopped
-
- MOV AX,4CFFh ; terminate process
- INT 21h
- ENDP
-
- ;--------------------------------------------------------------------------
-
- SwapInXMS PROC
- PUSH DS ; save DS from Turbo Pascal
- MOV AX,CS
- MOV DS,AX ; DS = CS
- MOV ES,AX ; ES = CS
- CLD
- LEA DI,XMSStructur ; CS:DI = Pointer ad XMS structure
- LEA SI,SaveSize ; CS:SI = memory we use
- MOVSW ; save size
- MOVSW ; in structure
- MOV AX,Handle
- STOSW ; source handle <> 0 -> XMS
- XOR AX,AX
- STOSW
- STOSW ; offset source = 0
-
- STOSW ; handle destination = 0
- MOV AX,OFFSET SavePoint
- STOSW
- MOV AX,SEG SavePoint
- STOSW ; start adress
-
- MOV AH,0Bh ; XMS : "copy block"
- LEA SI,XMSStructur ; DS:SI = pointer at structure
- CALL XmsPointer ; XMS Call
- POP DS
- CMP AX,1 ; CY = 0 if equal
- JNE @@XMSerror
- RET
- @@XMSerror:
- ; if a error occures, the program must be stopped
-
- MOV AX,4CFFh ; terminate process
- INT 21h
- ENDP
-
- ;--------------------------------------------------------------------------
-
- EVEN
- SavePoint: ; ******* First point to save **********
-
- ;--------------------------------------------------------------------------
-
-
- ; -----------------------------------------
- ; Variables who are not nedded for swap in
- ; -----------------------------------------
-
- ;-------- variables used for DISK
-
- TmpName DB 256 DUP (?)
-
- ;------- variables used for EMS
- EVEN
-
- EMSDeviceName: DB 'EMMXXXX0'
-
- ;-------- variables used for XMS
-
- XMSStructur XMSstrucTyp ?
-
- ; ----------------------------------------------------------------------------
- ; All functions who are not uses while/after swap out
- ; ----------------------------------------------------------------------------
-
- ;-----------------------------------------------------------------------------
- ; calculate the bytes to save
- ;-----------------------------------------------------------------------------
-
- BytesToSave PROC
-
- MOV AX,CS
- MOV BX,10h
- MUL BX
- LEA BX,SavePoint
- ADD AX,BX
- ADC DX,0 ; DX,AX = first adress to save
-
- PUSH DX
- PUSH AX
-
- MOV AX,ES ; AX:CX = last adress as pointer
- MOV BX,10H
- MUL BX
- ADD AX,CX
- ADC DX,0 ; DX,AX = last adress as 32 Bit adress
-
- POP BX
- POP CX ; CX,BX = first adress as 32 Bit
-
- SUB AX,BX
- SBB DX,CX ; DX,AX = Size
-
- RET
-
- CalcErr: MOV AX,0
- MOV DX,0
- RET
-
- ENDP
-
-
- ;-----------------------------------------------------------------------------
- ; Copy data from variables in DS to variables in CS and calculate
- ;-----------------------------------------------------------------------------
-
- CopyFromTurbo PROC
- MOV AL,Method
- MOV MethodCS,AL
-
- CopyPascalString FileName,ProgPathName ; copy program name in CS
-
- ; copy parameters into code segment
-
- PUSH DS
- LDS SI,Parameter ; DS:SI -> pointer at parameter
-
- MOV AX,SEG ProgParam
- MOV ES,AX
- LEA DI,ProgParam ; ES:DI -> pointer at code segment
-
- LODSB ; size of string in AL
- STOSB ; copy to CS
- CMP AL,0 ; empty string ?
- JE @@emptyString
- MOV CL,AL
- XOR CH,CH ; CX = size
- REP_FastMovs ; copy string from DS to CS
- @@emptyString:
- MOV AL,0Dh ; = CR
- STOSB ; last char must be a CR
- POP DS ; the old DS
-
- MOV AX,PrefixSeg ; get PSP
- MOV MyPSP,AX ; and save it in CS
-
- DEC AX ; the MCB
- MOV ES,AX ; ES = MCB
- MOV AX,ES:[0003h] ; AX = paragraphs owned now
- MOV MaxSize,AX ; save this origin size
-
- ; ---- calculate the programs size after swap out
-
- ; sP = adress "SavePoint"
- ; size in byte = OFF (sP) + SEG (sP)*16 - SEG (PSP)*16
- ; size in parag.= OFF (sP) / 16 + SEG (sP) - SEG (PSP)
- ; allway round up !
- ; size in parag.= OFF (sP + 15) / 16 + SEG (sP) - SEG (PSP)
-
- MOV AX,OFFSET (SavePoint+15) ;
- MOV CL,4
- SHR AX,CL ; AX = AX / 16
-
- ADD AX,SEG SavePoint
- SUB AX,MyPSP ; AX = min paragraphs
- MOV MinSize,AX
-
- ; ------ calculate the size needed to swap out
- ; ------ must been the last in this function !!!!
-
- LES CX,[LastAdr] ; ES:CX = last adress to save
- MOV EnAdress.Segm,ES
- MOV EnAdress.Ofst,CX
- CALL BytesToSave ; returns in DX,AX size
- MOV SaveSize.lo,AX
- MOV SaveSize.hi,DX
- ADD DX,AX
- CMP DX,0 ; size = 0 = error !
-
- RET
- ENDP
-
- ;-----------------------------------------------------------------------------
-
- INCLUDE FSWAP.INC
-
- ;-----------------------------------------------------------------------------
-
-
- END
-
-